package org.tio.showcase.dbUtil;

import java.util.Map;

import com.alibaba.fastjson.JSON;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;


/**
 * 非切片链接池
 * 备注:redis连接池 操作工具类
 * 提交：qinxuewu
 * 时间：2015年8月19日上午8:59:24
 */
public class RedisUtil {
    //public static JedisPool jedisPool; // 池化管理jedis链接池

	//服务器IP地址
	private static String ADDR = "127.0.0.1";
	//端口
	private static int PORT = 6379;
	//密码
	private static String AUTH = null;
	//连接实例的最大连接数
	private static int MAX_ACTIVE = 1024;
	//控制一个pool最多有多少个状态为idle(空闲的)的jedis实例，默认值也是8。
	private static int MAX_IDLE = 200;
	//等待可用连接的最大时间，单位毫秒，默认值为-1，表示永不超时。如果超过等待时间，则直接抛出JedisConnectionException
	private static int MAX_WAIT = 10000;
	//连接超时的时间　　
	private static int TIMEOUT = 10000;
	// 在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
	private static boolean TEST_ON_BORROW = true;

	private static JedisPool jedisPool = null;
	//数据库模式是16个数据库 0~15
	public static final int DEFAULT_DATABASE = 5;
	/**
	 * 初始化Redis连接池
	 */
	static {
		try {
			JedisPoolConfig config = new JedisPoolConfig();
			config.setMaxTotal(MAX_ACTIVE);
			config.setMaxIdle(MAX_IDLE);
			config.setMaxWaitMillis(MAX_WAIT);
			config.setTestOnBorrow(TEST_ON_BORROW);
			jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT,AUTH,DEFAULT_DATABASE);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取Jedis实例
	 */

	public static Jedis getJedis() {

		try {
			if (jedisPool != null) {
				Jedis resource = jedisPool.getResource();
				System.out.println("redis--服务正在运行: "+resource.ping());
				return resource;
			} else {
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

    /**
     * 获取 redis链接
     *
     * @return 2017年9月13日
     */
    public static Jedis getResource() {
        return jedisPool.getResource();
    }


    /************************************************String Key 类型*******************************************/

    /**
     * 向缓存中设置字符串内容
     * 失败返回0  不覆盖 成功 返回1
     *
     * @param key   key
     * @param value value
     * @return
     * @throws Exception
     */
    public static long setnx(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();

            return jedis.setnx(key, value);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedis.close();
        }

        return 0;
    }


    /**
     * 成功返回  OK
     * 向缓存中设置对象(自动把对象转换成json数据存储到缓层中)
     *
     * @param key
     * @param value
     * @return
     */
    public static long setnx(String key, Object value) {
        Jedis jedis = null;
        try {
            String objectJson = JSON.toJSONString(value);
            jedis = jedisPool.getResource();
            return jedis.setnx(key, objectJson);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedis.close();
        }

        return 0;
    }

    /**
     * 删除缓存中得对象，根据key
     *
     * @param key
     * @return
     */
    public static boolean del(String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.del(key);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            jedis.close();
        }

    }


    /**
     * 根据key 获取内容
     *
     * @param key
     * @return
     */
    public static Object get(String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            Object value = jedis.get(key);
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            jedis.close();
        }

    }


    /**
     * 根据key 获取对象
     *
     * @param key
     * @return
     */
    public static <T> T get(String key, Class<T> clazz) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String value = jedis.get(key);
            return JSON.parseObject(value, clazz);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            jedis.close();
        }
    }


    /***
     * 检查key是否存在
     * @param key
     * @return
     * true 存在
     * false 不存在
     */
    public static boolean checkExists(String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.exists(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            jedis.close();
        }

    }


    /***
     * 往指定的key追加内容，key不在则添加key
     * @param key
     * @param value
     * @return
     */
    public static boolean appendStr(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.append(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            jedis.close();
        }
    }

    /***
     * 批量获取key的value值
     * @param keys
     * @return
     */
    public static Object bathKey(String[] keys) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.mget(keys);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            jedis.close();
        }

    }

    /***************************************hashes(哈希)类型*********************************************************/

    /**
     * 设置hash field
     * 如果存在不会设置返回0
     *
     * @param key
     * @param field
     * @param value
     * @return 成功返回1, 失败  0
     */
    public static long hsetnx(String key, String field, String value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.hsetnx(key, field, value);
        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            jedis.close();
        }
        return 0;

    }

    /**
     * hget取值(value)
     *
     * @param key
     * @param field
     * @return
     */
    public static Object hget(String key, String field) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.hget(key, field);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            jedis.close();
        }
    }

    /**
     * hmset 批量设置值
     *
     * @param key
     * @param hashmap
     * @return 成功返回OK
     */
    public static String hmset(String key, Map<String, String> hashmap) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.hmset(key, hashmap);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedis.close();
        }
        return null;
    }

    /**
     * hmget 批量取值(value)
     *
     * @param key
     * @param fields
     * @return
     */
    public static Object hmget(String key, String... fields) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.hmget(key, fields);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            jedis.close();
        }
    }

    /**
     * @param key
     * @return 返回所有的key和value
     */
    public static Map<String, String> hgetall(String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.hgetAll(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            jedis.close();
        }
    }


    /***************************************list(列表)*********************************************************/


    /**
     * lpush 设置值 从头部压入一个元素
     *
     * @param key
     * @param strings
     * @return 成功返回成员的数量  失败返回0
     */
    public static long lpush(String key, String... strings) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.lpush(key, strings);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedis.close();
        }
        return 0;
    }
	/**
	 * lpush 设置值 从尾部压入一个元素
	 *
	 * @param key
	 * @param strings
	 * @return 成功返回成员的数量  失败返回0
	 */
	public static long rpush(String key, String... strings) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			return jedis.rpush(key, strings);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			jedis.close();
		}
		return 0;
	}

    /**
     * list列表取值(lrange)
     *
     * @param key
     * @param start
     * @param end
     * @return start=0  end=-1(代表从开始到结束)
     */
    public static Object lrange(String key, long start, long end) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.lrange(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedis.close();
        }
        return 0;
    }


    public static String rpoplpush(String key, String dstkey) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.rpoplpush(key, dstkey);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedis.close();
        }
        return null;
    }

    public static String rpop(String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.rpop(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedis.close();
        }
        return null;
    }


	/**
	 * 设置key 过期时间，单位 秒
	 * @param key
	 * @param seconds
	 */
	public static void expire(String key, int seconds) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.expire(key,seconds);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			jedis.close();
		}
	}
}